home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
C/C++ Interactive Reference Guide
/
C-C++ Interactive Reference Guide.iso
/
c_ref
/
csource5
/
304_01
/
roff5.doc
< prev
next >
Wrap
Text File
|
1990-02-14
|
47KB
|
1,314 lines
August 29, 1989
ROFF5, V2.00
by Ernest E. Bergmann
730 Seneca Street
Bethlehem, PA 18015
ROFF5 is a major revision of my earlier formatter,
ROFF4, v1.61. It has been written in Turbo C, v2.0 (MS-DOS)
for greater portability. It has many significant extensions.
However, some of the old commands have been changed in order
to more closely align with the venerable formatters: nroff
and troff. Many of the exceptions are due to the influence of
WORDSTAR [tm by MicroPro] or personal taste.
ROFF4 is an expanded version of ROFF, based on the
formatter in Kernighan and Plauger's book SOFTWARE TOOLS, is
written in BDS C, and employs the directed i/o functions
that go along with that package. Well, half of the directed
I/O anyway - it doesn't use redirected input because more
than one file can be used as input for a run. So that some
of the input files may be used to "set-up" the formatter for
a particular style and for particular hardware. It is
possible to substitute keyboard input instead of files for
educational and test purposes.
ROFF was provided by Neal Somos for the public
domain via the BDS 'C' Users' Group's volume, CUG -- "Just
Like Mom's". Some of this documentation started there as
well.
This formatter contains features important for the
preparation of technical manuscripts. Special symbols or
fonts that can be defined by or for the user can be produced
(if the hardware is capable!). Super and subscripts can be
handled as well as backspace even for printers without
reverse scrolling or backspacing hardware capabilities.
However, the output device should recognize separately the
<CR> and <LF> functions.
Because of the strong similarity to the nroff and troff of
UNIX[R by AT&T], documentation of those formatters would be relevent
here. In particular, I recommend the paperback book, "troff
Typesetting for UNIX[TM] Systems," by S. L. Emerson and K. Paulsell,
ISBM 0-13-930959-4. I have tried to avoid using command names that
are inconsistent with troff, but I have not strictly followed the
same conventions because I place a higher premium on longer names
for ease of documentation and I want to directly drive simple
devices such as a variety of dot matrix printers with special
symbols that are sometimes needed in technical manuscripts. I have
personally used ROFF4 and ROFF5 for dozens of manuscripts. I have
thus located and fixed bugs and determined features that appeared to
make sense.
"Preprocessor" files and directives can be used to merge
stock phrases, boiler plate, make macro definitions, automate
numbering, and create diversions (for footnotes, table of
contents, etc.)
To support the capabilities of WORDSTAR[tm by
MicroPro] extended underlining, strikeout, and multiple
strike capability are provided as well.
-----------------------------------------------------------------
The MS-DOS version uses the curly-bracket character '}'
to redirect output, and only one target may be
specified. Thus:
a>roff5 filename1 filename2 }outfile
would format filename1 and filename2 and write the output
on a file "outfile" on the default drive. If there is no
target specified, the default output is the console.
The more conventional character '>' is not used because
MS-DOS 2.x intercepts any '>' or '<' on the command
line and redirects all output to the specified target,
even output which the program addressed to 'stderr'.
_________________________________________________________________
A>roff5 -s -f filename1 filename2 -f -m -r -i -g -*
The option, -s, causes the formatter to stop (pause)
at the start of each page of output; the bell at the
console is sounded (if it exists!) and the program
waits until any key is pressed at the console. It
is essential for printers that are feed single sheets
at a time!
An option that was not shown above, -o[page or range],
is used to selectively generate output of ONLY certain
pages. It is useful to retype pages that got "eaten"
by the printer (Henry Harpending's aptly put language).
To retype only page 23, say, make the option: -o23
To retype pages 23 through 29 use: -o23-29
To retype pages 23 to the end use: -23-
These options changes the values of the internal
variables, FIRSTPAGE and LASTPAGE which originally
have the values of 1 and 30000, respectively. Normally
this option would be placed early enough in the
command line that no pages have been printed yet.
Another option that was not shown above, -n[page#],
is used to change the default starting page number.
The option, -f, would introduce a formfeed (0CH)
into the output stream (useful for placing blank
pages, or aligning printer pages) where it appears;
in this example, before the first page of output,
and, again, at the very end of the output.
The option, -m, causes a list of macro definitions
to be typed to the console. It is a useful tool for
debugging complex macro packages where the
preprocessor's expansions are too subtle for humans.
The option, -i, causes a list of string insertions
to be typed to the console. Useful for macro writers,
as was the -m, described above. Also, for noting
what are the settings of "standard substitutions",
such as "today's date".
The option, -r, causes a list of number registers to
be typed to the console. Could be useful to find
the number of footnotes, etc.
The option, -g, causes a glossary of defined
translated characters to be printed on the output
device. It is useful to check the appearance of
all special definable characters and to produce
a "wall chart" of special characters available.
The default option, -*, (the * could be any
unassigned option) means keyboard input (buffered
line-by-line with a prompt with the character used in
the option, here *). Typing a control-Z indicates
an end-of-file; the formatter will continue with the
next named file. It is intended as a learning aid
since one can tryout "tricky" input such as
equations. As with standard CP/M and MS-DOS, a
control-P can be used to toggle the printer to
display output that would normally be sent to the
console; also, one can edit the keyboard input with
the backspace key.
Using ROFF5, you can make nice printouts of a file,
with as little or as much help from the program as you want,
depending on the commands. There are default values for all
parameters, so if you don't put any commands in at all, your
file will come out with filled, right-justified lines. The
default line-length is 66 characters and we have defaulted the
conventional tab stops to every fifth column; the default page-
length is 66 lines per page. "Filled lines" means that as
many input words as possible are packed onto a line before
it is printed; "non-filled" lines go through the formatter
w/o rearrangement. "Right-justified" simply means that
spaces are added between words to make all the right margins
line up nicely. To set a parameter, use the appropriate
commands below. All commands have the form of a period
followed by one or two characters; any non-blank contiguous
non-blank characters following a recognized command will be
passed over by the formatter. Thus, ".else" could be used
instead of ".el". A command line should have
nothing on it but the command and its arguments (if any);
any text would be lost.
Extra space will separate text sentences. The sentence
is recognized by a trailing ':',';','!','?', or a '.'. For
the '.' there is the additional requirement that either two
or more spaces must follow it, or that it is at the end of
the source line.
A command argument can be either ABSOLUTE or RELATIVE :
.ls 5 sets the line spacing to 5
.ls +5 sets the line spacing to the CURRENT value+5
.ls -1 sets the line spacing to the CURRENT value-1
Also, all commands have a minimum and maximum value
that will weed out any odd command settings (like setting
the line spacing to zero, for example. It won't let you do
that, but it could be changed if you REALLY have a burning
desire to do so).
Some commands cause a "break", which is noted in the
table below. Before such a command goes into effect, the
current line of text is put out, whether it is completely
filled or not. (this is what happens at the end of a
paragraph, for example.) A line beginning with spaces or a
tab will cause a break, and will be indented by that many
spaces (or tabs) regardless of the indent value at that time
(this is a "temporary indent", which can also be set
explicitly). An all blank line also causes a break.
We part company with ROFF4, nroff, and troff by not having as
many commands produce a break; we reasoned that one can more
easily add the .br where needed (and still be compatible with these
other formatters). If you find that some lines that are indented
strangely, and it's not obvious WHY, look at which commands are
causing a break, and which aren't.
Certain system variables are "stacked" to enable
reversion to earlier environments instead of "hardcoded"
defaults. For example:
.ls 1
.
.
.
.ls
The first command will produce single line spacing (which is
the default, but which may have been set otherwise at the
beginning of the manuscript). The second command causes
resumption of the original line spacing (either the default
or whatever had been chosen previously). Stacked variables
include: linespacing, indent column, right margin,
translation flag character, page length, top and bottom
margin sizes, unexpandable space character, insert character,
environment, and control flag character.
*********************** Table of Commands *********************
Command Break? Default stacked Function
------- ------ ------- ------- ---------
.. string no string is "mere"comment
.;; no end the macro definition
.{ no start a group of lines subjected
to conditional, such as ".if"
.} no end group started by ".}"
.ab string no USER ABORT immediate abort back to
system
.ad c both both No adjust margins; c=b(oth),
l(eft), r(ight), c(enter)
[if "filling" also]
.af name picfmt no assign format to number reg.
(see "PREPROCESSOR")
.am name append to macro or create.
.bj yes break with right
justification (current
line only)
.bp n yes n = +1 begin page numbered n
.br yes cause a break (this
line is not justified)
.ce n yes n = 1 center next n lines
.cf c no c = '^' Yes to be used as a prefix
to a character that
controls print func-
tions such as ^+,^-
might be used to
bracket superscripts,
somewhat like
WORDSTAR(TM).
.ch macro n no relocates a .wh request.
.cz n no control-Z substitution out.
.da name no (end diversion) append or create a diversion
.de name no define (multiline)
macro ("PREPROCESSOR")
.di name no (end diversion) start diversion named name
(see "PREPROCESSOR")
.ds name string no string="" no define string replace-
ment ("PREPROCESSOR")
.ef /../../../ no blanks even footer titling
.eh /../../../ no blanks even header titling
.em name (removes) End Macro; acts if .name
was placed at end of last
file read in.
.el anything no "Else" part of .ie ...
.ev n no 0 yes switch environments
.fi yes start filling lines
.ff n no n = 1(yes) initially, formfeeds
are "off". Can turn
them on. Each page
then terminated with
one formfeed.
.fo /../../../ no empty sets both even and odd
page footers
.fr # base - ; no 1,no action defines how to put
- - - - . output device in mode
for fractional and whole
line spacing (for super-,
sub- scripting); see
"PRINTER CONTROL",
given below.
.go n go (advance) to line n.
.he /../../../ no empty sets both even and odd
page headers
.ic c no c = '\' Yes? to specify the interpolation
character used for macro
string and register
preprocessing.
.ie expr anything no expr=FALSE begin If-Else cond. macro.
.if expr anything no expr=FALSE If expr non zero, then anything.
.ig string no "ignore" following lines until
.string line is found
.it n macro no removes n sets input trap.
.lc c no blank No Leader expansion Character;
initially '.'.
.ls n no n = 1 Yes set line spacing to n
.m1 n no n = 2 Yes set topmost margin to n
.m2 n no n = 2 Yes set 2nd top margin to n
lines
.m3 n no n = 2 Yes 1st bottom margin to n
lines
.m4 n no n = 2 Yes bottom-most margin to n
lines
.mc [not yet implemented]
.ne n no/yes n = 2 /yes "need" n lines; if have
them no action; else
begins new page
.na no initially turn off justification
is justifying [only relevent
if "filling" also]
.nf yes stop filling lines
.nm N M S I No line Number Mode.
.nn n n=1 No No line Numbering.
.nr name n no n=0 No create or modify number
register variable
(see "PREPROCESSOR")
.of /../../../ no empty odd page footer title
.oh /../../../ no empty odd page header title
.ot ~c|^c base - ; no not applicable used to create
- - - . definitions for special
character fonts/printer
control.
.ou base - - ; no not applicable direct output of code
- - - . sequences to output.
.pc [not yet implemented]
.pl n no n = 66 Yes sets page length to n
.pm no print macros to stderr.
.po n n=0 n=0 No page offset.
.rl ?/string no ignore shows/sets line and tab format.
(see RULER...)
.rm names1 ? names2 removes definitions named names1
and named names2; error message
for not finding names2 only.
.rn old new no (error) rename definition; names
must be same length.
.sc c no blank Yes space character; the
visible character
that will be trans-
literated to unexpanded
blank.
.so filename no ignored Yes reads named file into
input stream; cannot be
invoked from keyboard
input.
.sp n yes n = 1 space down n lines
.st n no n=1(yes) stop(pause)at each page
start; initially off;
may also be enabled by
the -s option.
.tc c no blank No tab expansion or fill
character.
.tf c no '~' Yes Translation flag character.
.tl 'string1'string2'string3' generates 3 part title.
.tm string terminal message;
like a comment
but displayed to
operator during run.
.ti [+-]n yes n = 0 set temp. indent of n
optional sign is relative
to normal left margin.
.wh n macro no no action "when" trap springs macro at
line n on output pages.
-------------------------------------------------------------
Here's what the page parameters look like:
(.po)-->|
_ _________________________________________________
| | top margin(m1) - (includes header) |
| |-----------------------------------------------|
| | top margin 2 |
| |-----------------------------------------------|
P | : : |
A | :<-indent : |
G | : : |
E | :lots and lots of silly text and: |
L | :other garbage. Get the picture?: |
E | :This is a temp. indentation: |
N | : : |
G | : right margin -> : |
T | : : |
H | : : |
| |-----------------------------------------------|
| | margin 3 |
| |-----------------------------------------------|
| | margin 4 - (includes footer,perhaps ff) |
- -------------------------------------------------
Minimum acceptable values for M1, M2, M3, and M4; if M1 is set
to zero, no header will be shown (even if one was declared).
Similarly, if M4 is set to zero, no footer will be displayed.
To change the default for any parameter, simply alter ROFF5.H
and recompile and link.
------------------------------------------------------------
The numerical argument, n, and the expression, expr, of the
conditional commands (.if and .ie) can be calculated or evaluated by
ROFF5. For example, ".sp 3+4" is equivalent to ".sp 7". A leading
"+" or "-" sign is still used to indicate "relative" values. For
example, ".ti -1+1" is equivalent to ".ti -2". There should not be
any white space within the expression. A leading "!" can be used to
convert a "true" expression to "false", and vice versa.
Calculations use the usual precedence rules where
parenthesized portions are evaluated first, multiplication and
division are evaluated left to right, addition and subtractions are
then evaluated (also left to right) and, lastly, the logical and
comparison operations are performed left to right. The logical
"and" and "or" are represented by the symbols "&" and ":",
respectively. A subexpression is "true" if non-zero and "false" if
zero. The comparison operations are: "<", "<=", "=", ">=, and ">".
One can use number registers in expressions by using "\"s in
sufficient quantities to bracket them [see the section on the
"PREPROCESSOR", below]. For register names which are beginning with
a letter and consist of only letters and numbers (such as "date",
"x1", "name23", etc.) the evaluation will convert them automatically
(they must already be defined!).
***********************************************************
A Few Extra Comments on Some of the Commands:
************************************************************
If you want to center lots of lines, but don't
want to count them, do something like this:
.ce 1000
lots and
lots of words to
be centered
.ce 0
--------------------------------------
A new paragraph may be caused by using the temporary indent
command, like
.ti +5
or by simply beginning the paragraph with a tab, as you would
if you were just typing. If there is an indented left margin by a
ruler command of the general form:
.rl " L---...etc. R" ,
one can have "hanging" temporary indents by using a negative value
for the numerical argument.
------------------------------------
For special cases, where you wish to place the last
"word" at the right-hand margin, such as numbers of equation,
for example:
x = y+z (12)
you could input:
# x#=#y+z (12)
.bj
because we force a break with justification (.bj) of the
line with only "three words". (The # is assumed to be the
"space character" set up with a .sc command).
Other ways we could achieve similar results for equations
would be to use the .tl (title) command:
.tl //x = y+z/(12)/
or to set up a special environment and use tabs.
------------------------------------
Headers, Footers, and Titles.
A page number can be incorporated into any header, footer,
or title by putting a "#" into the command line where you want the number
to go:
.he /This is a witty header title for page #/
Each time this is printed at the top of a page, the current
page number will be substituted for the "#".
Headers, footers, and titles are in three parts. These parts are left
justified, centered, and right justifed. Any of these three
parts may be left out. The right justification is fixed to the
margin that is set by the .OW command. One may pick the
headers and footers separately for even and odd pages. For
example, one could place even and odd page numbers at the
bottom outside of each page by:
.ef /Page #///
.of ///Page #/
Any printable character, here the '/', can be used to
delimit the three strings that make up the titles, so long
as it is not the "insert character" (usually, '\') and is
not present in any of the three strings.
Headers and footers obey margins established for environment
1; titles (created from the .tl command) are processed in the
current environment. They all are not considered text lines; they
are not counted by the line numbering provided by the .nm command.
------------------------------------
The program can be made to wait for the operator to
load single sheets of paper by the -s option and/or by the
command: .st
------------------------------------
If you want to send the output to a file, and don't want the
page breaks in there set margins 1-4 to zero.
------------------------------------
Where you need to supply code sequences for
immediate or for subsequent output (for .ou or for .ot) one
needs to supply the number base (binary, octal, decimal, or
hexadecimal) by supplying a token that begins with (upper
and lowercase are both o.k.): b, o(or q), d, or h. Following
the base on the same and/or subsequent lines one supplies
the codes that will form the "code string". These codes are
delimited by white space (not commas!) and the sequence is
eventually terminated by a token beginning with a period.
The ends of any of these lines may contain comments if they
are set off by white space and a semicolon. For examples:
.ou hex 11 1C 8C 0
99 6C 55 ;get ready!
.end
.ot ~= binary ;"identity"operator (triple equal sign) on MX-80
00011011 ;ESC
01001011 ;4B
00000110 ;6 bit patterns
0 ;follow:
00101010 ;left top,bot
00101010
00101010
00101010
00101010
00000000 ;right top,bot
.end
The first of these examples might be used to get
some strange printer to cooperate in standing on its head or
something.
The second, lengthier example is taken from a file,
MX, that defined quite a number of special characters for
the MX-80 with GRAFTRAX 80. Because that printer uses dot
graphics, I chose to make the definition in binary so that
the placement of the individual dots is easier to visualize.
Later, in the text the combination: ~= will cause the
printer to be sent this code so that it will print the
specialized symbol.
SPECIAL SYMBOLS
If one includes a set of definitions such as in the
MX file, one can specify the use of special symbols, which
can be chosen to fit the application (and the hardware!) For
example, the MX-80 printer equipped with GRAFTRAX 80 can
accept dot addressed graphics. [See the MX file for
examples with this hardware]. Other printers may be able to
simulate symbols by a combination of overstruck characters.
Still other output devices may be capable of displaying
desired special symbols by use of the "parity bit".
The .ot and .tf commands define the codes for the
special symbols and the translation flag character. To create a
"wall chart" that lists the special characters on the output
device you could use the -g option on the command line, for
example:
A>roff5 mx80 -g )
====================================
PRINTER CONTROL
It is assumed that the output device can accept
carriage returns and will not linefeed in the absence of the
linefeed character. Using this assumption, super- and
subscripting, backspacing, underscoring, strickout, and
multiple impressions are supported in a manner somewhat
analogous to WORDSTAR [tm by MicroPro], but more generally.
If the printer can be placed in fractional
linespacing mode, so much the better, as full line spacing
for super- and subscripts does not look as "natural". Also,
with the half line spacing, one can build up larger
characters (such as summation and integration symbols) since
some overlap does occur. To implement such fractional
spacing one uses the command: .fr (probably at the
beginning of the input file, along with other information
relevent to the output device and style). These commands
describe the operational codes sent to the output to switch
the printer to FRactional spacing and back to whole line
spacing.
For example, I use for the MX-80 printer equipped
with GRAFTRAX 80 the following:
.fr 1 HEX 1B 32 . ;(whole line) 6 lines/inch is standard
.fr 2 hex 1b 33 12 . ; 18/216" = halfline spacing
The initial 2 in the second .fr tells the formattter that 2
fractional [half] lines are equivalent to a conventional whole
line. The original description of the required codes were in
hexadecimal, so I kept matters as simple as possible by
using the same number base so that I would not make any
conversion mistakes!
The printer control requests are embedded in the
text; they are NOT set off in separate lines as the "dot"
commands are set apart. Each request is made up of two
printable characters, the first of which is the "control
flag character" (the default is '^'). Here is a table of
control functions presently supported by ROFF5,
version 2.00:
^+ up a fractional line; may be used several times to
increase vertical rise. [used at start of a
superscript and at the end of a subscript]
^- down a fractional line; may be used several times to
increase vertical drop. [used at the start of a
subscript and at the end of a superscript]
^h,^H backspace one character column. Do NOT backspace
over ordinary blanks ("unexpandable" space is o.k.)
if you are in "fill" mode.
^(,^) Note current column position; return to noted position.
^[,^] " " " " " " "
^{,^} " " " " " " "
The above three pairs of controls are often more
convenient then multiple, explicit backspaces, ^H,
especially for "built-up" fractions and matrices.
^A,^a Leader character, similar to a tab, but typically used with
a leader repetition character, such as '.', to form table
of contents entries.
^B,^b Start, end boldface (increase, decrease the number
of impressions by a factor of 3).
^D,^d Start, end doublestrike (increase, decrease the number
of impressions by a factor of 2).
^T,^t Tabs typically used for paragraphs and for coulumnar
information; although usually used only for motion, it can
mimic the leader character by defining some tab expansion
character with the .tc command.
^U,^u Start, end underscore (will not underscore
expandable white space; will ride up and down with
super and subscripts.)
^X,^x Start, end strikeout (similar to underscore, above,
but overprints with '-' instead of underlines).
Note that the B, D, U, and X pairs are "case sensitive";
namely, the uppercase starts some activity, whereas the
lowercase equivalent sqelches it; these controls are
NOT "toggles".
An involved example of the use of printer controls
would be to create a 3 by 3 matrix:
MATRIX =#^+^+^(|1#2#3|^)^-^-|4#5#6|^)^-^-|7#8#9|^+^+
which should produce (with a half-spacing) printer:
|1 2 3|
MATRIX = |4 5 6|
|7 8 9|
[the demonstration file, MATRIX, has been provided as a
demonstration of the above].
Several points should be observed. There should be no
expandable blank spaces if you are in fill mode, otherwise,
the result might be very strange! (ROFF5 does some checks to
flag such attempts). We are assuming here that the '#' are
unexpandable spaces (chosen with the .sc command). The
first printable character in the complex, the '=', is at the
leftmost edge; the last printable character, the '|'
following the '9', is at the rightmost edge of this
assemblage. The final height is adjusted (by the trailing
^+^+ ) to match the initial height. The present limit of
the line buffering is 255 characters; I assume that is not
too chancy.
One can define additional printer control codes
using the .ot command. For example, the MX-80 printer with
Graftrax is switched to italics with the sequence <ESC> '4';
and italics are turned off with <ESC> '5'. We could define
^I to start italics and ^i to end them:
.ot ^I hex ;italics on (MX-80 & Graftrax)
1B 34
.en
.ot ^i hex ; italics off (MX-80 & Graftrax)
1B 35
.en
================================
RULER LINE AND TABS
===== ==== === ====
We liked the idea introduced by WordStar(TM by MicroPro) of
the "ruler line" which is a picture description of the location for
margins, and tab stops. It can facilitate the composition of
tabular information. Our implementation is neither close to that of
WordStar nor to Unix(R by AT&T)'s nroff or troff. We hope that we
have achieved the best of the two, in terms of convenience, clarity,
and of flexibility.
Each environment has its own ruler; its ruler can be
set or changed or observed at anytime by use of the .rl command. We
include here a brief example to illustrate how it is used:
.nf
.rl " L---------l---------c----------r---.-----,-----R"
.rl ?
x^Txxxxx^txxxxx^Txxxxx^Tx.xx^txx,x
.fi
Now is the time for all good persons to come to the aid of their
country... x^Txxxxx^txxxxx^Txxxxx
x^Txxxxx^txxxxx^Txxxxx^Tx.xx^txx,x
The first line declares that we are to be in "no fill" mode so that
we can see the effects of the tab settings; this mode is most
appropriate to presenting tabular information. The second line sets
or changes the "ruler line". The "L" and "R" are locating the left
and right margins of future output. In order to "see" the 5 leading
blanks (so that we can indent 5 spaces) we have enclosed the string
argument in double quotes. The third line uses the same command,
but with the argument, "?" which will cause the ruler line to be
displayed in the output.
To explain the remaining actions we shall show the output
that would be produced:
L---------l---------c----------r---.-----,-----R
x xxxxx xxxxx xxxxx x.xx xx,x
Now is the time for all good persons to come to
the aid of their country... x xxxxx xxxxx xxxxx
x xxxxx xxxxx xxxxx x.xx xx,x
In keeping with our design philosophy that the input stream should
be printable on any generic ASCII device (and be visually scanned
unambiguously), we did not want to require that actual tabs (ascii
8) be used. We can use the character pairs, "^t" or "^T", instead.
The forth input line contains short words of x's separated by the
character pairs representing tabs.
We see in the first two output lines, shown above, that we
have the current ruler line and how it causes the tabs to be
processed. The "l" in the ruler line indicates a (conventional)
"left" tab stop. Such a tab stop causes the output to be advanced
horionatlly so that the next character begins with that position;
it provides alignment of the left edge. The "c" in the ruler line
indicates a "centering" tab position; we see that the next tabbed
group of x's are centered under it. Similarly, the "r" indicates a
right tab stop for alignment of right edges. We have provided two
other tab position types indicated by "." and ","; they provide
alignment for decimal point data, such as financial information, for
both American and European usages.
When the input reverts to "fill" mode by the use of the .fi
command, the tab positions loose much of their significance (except
for leading tabs, say, for the start of a paragraph). However, the
right and left margins are most important for controlling the fill
mode's line sizes. The tabs that are used to separate words now are
treated as equivalent to spaces in the input stream.
================================
OFFSETS
=======
We shall describe the different ways that the lines of
output are offset from the left-hand margin. The page offset is
controlled by the .po command. It is usually set once, and only
before any output has been generated. It is intendended to locate
the page relative to the output device's left-hand physical edge.
The printed lines are usually controlled by the .rl command,
as was described above. In order to simplify indenting or having a
hanging indent at the start of a paragraph, we have the .ti
(temporary indent) command that can affect only the next line that
is being placed on the page. It can be absolute (relative to the
page offset, anyway), or by using an argument preceeded by a "+" or
"-" can be relative to the current indent (determined by .rl).
When one uses automatic line numbers in the margin by means
of the .nm command, the text margin is indented additionally to make
space for the numbers that will occupy the margin. The 4 parameters
for this command are somewhat complex, but we have followed (I
think) the nroff/troff conventions here. Not all the parameters
need to be supplied. The full command, .nm N M S I, provides the
following options: N specifies the number used at the start of
line counting; M specifies the multiple number of lines between
display of the count (M=5 would display 5,10,15,etc.); S provides
the choice of spacing between the end of the number and the
beginning of text (default is 1); "I" specifies an indent between
the line numbers and the left margin.
It should be noted that the numbering is for lines of text,
not for blank lines nor for titles, either produced by the .tl
command or by header and footer commands. Also, note that the "no
numbering" request (.nn) does not negate all of the effects of .nm;
to completely finish numbering, one should use ".nm" (no
arguments).
================================
THE PREPROCESSOR
=== ============
In the following we describe the advanced macro
preprocessing features of this formatter which provide users
with labor saving tools but which are probably not necessary
at first. The beginning user may be able to achieve most
goals without the "preprocessing", but by using an editor
more then otherwise. The more advanced user will begin to
appreciate these features more.
In the following discussion we will assume the
default insert character, '\', and the default command
character, '.', will be used. (It is rare that you should
change these anyway!)
The insert character is used to denote where a
replacement should be used. For example, in:
Today, \date\, is special.
the block, "\date\", would be replaced as this sentence is
being input. If a prior string definition of the form:
.ds date "January 1, 1983"
had been processed previously then the example, after text
substitution, would become:
Today, January 1, 1983, is special.
If no string definition had been provided for "date", the
user will be prompted while the formatter is trying to input
this sample line. The console will get some message like:
[Bell]Please define <date>:
Whatever you type in will be used to form an "effective" .ds
definition. This feature should be useful in applications
where information should be changed or updated each time the
formatter is run, such as today's date, the addressee's name
and address in a form letter, etc. A sample file, FORM is
included to demonstrate both of the above means to define
string substitutions.
An important restriction must be observed when using
"definitions on the run". They must not be first used
inside of multiline definitions (namely inside of .ou, .ot, .de,
and .fr) because the building of both definitions will cause them to
interfere with each other. ROFF5, v2.00 will test for such
contention and abort operation if one is found. An example of such
a situation and its remedy is shown below:
.tm chose 0 for DRAFT and 1 for CORRESPONDENCE
.ou hex
1B
3\font\
.end .ou
This example, which might be used to initialize the Okidata
Microline 92 printer to go into correspondence quality or
into draft quality printing would cause problems if "font"
is supposed to be defined here during execution. We are in
the midst of defining an output string for the printer (ESC
"0" or ESC "1") when we are asking ROFF5 to create
(simultaneously) a definition for "font"; the program will
abort rather than continue with the two definitions mangling
each other. Here is a modified version of above without the
problem:
.tm chose 0 for DRAFT and 1 for CORRESPONDENCE
.. this comment containing \font\ is "ignored"
.ou hex
1B
3\font\
.end .ou
The fix here is that the formatter will encounter "\font\"
in the comment and complete a definition for "font" before
tackling the .ou command; no simultaneous definitions, no
problems!
Similar to string definitions are register
variables, which are created and modified with the .nr
command. Variables are useful for enumeration such as
equation numbering:
.nr eqnum 1
would create a register named "eqnum" with the current value
of 1. The the text might use it with, say:
x = y+1 (\eqnum\)
which would be converted on input into:
x = y+1 (1)
A subsequent instruction:
.nr eqnum +1
would take the current value of "eqnum" and increase it by 1
(so that it would now be 2 in our example:
a = b+c (\eqnum\)
would become:
a = b+c (2)
There is a special, reserved insertion, \#\, which
will provide the current page number. It should prove
useful in setting up tables of contents (see "diversions",
below). Trivial examples of its use are to be found in the
files, BPTEST and MARGINS. In rare cases it may be off one
page because it may be read while between pages; how can one
handle the sentence, "This sentence is on page XXX," when the
sentence straddles two pages?
Since we have defined a special register name, '#',
we should comment on what happens if you create a register
instruction with that name, such as:
.rg # +1
You will be changing the value of the page number of the
FOLLOWING pages. This is useful for leaving gaps in the
pagination for later inclusion of full page illustrations.
This feature is demonstrated (tested) in the file, MARGINS.
I wish to thank Henry Harpending for suggesting this.
We can choose a variety of output formats for number
register display. If a register named "R", say contains the value,
3, we can have "\R\" be replaced by "3", by " 3", by
"....3","iii", " iii", " III", "c", "C", " C",
etc. by assinging a format to this register with the command:
.af R picfmt
where the form of picfmt indicates the minimum width of the field,
the representation of the numbe and the fill character used on the
left of the field if the representation of the number would
otherwise be less than the minimum field width. The picfmt may be
enclosed in quotation marks; this is important if it contains
blanks. The width of picfmt determines the minmum width of the
output representation, the leftmost character of it provides the
fill character to be used if necessary to pad the representation on
the left up to the minmum filed width. The rightmost character of
the picfmt choose the format:
char numbering
==== =========
1 0,1,2,3,4, etc.
i 0,i,ii,iii,iv, etc.
I 0,I,II,III,IV, etc.
a 0,a,b,c,..,aa,ab,..,aaa,aab,...
A 0,A,B,C,..,AA,AB,..,AAA,AAB,...
So, for example, to obtain 000,001,..010,011,..999 we could use the
picfmt of 001. Similarly, in a table of contents to
get ....i, ...ii, etc., we could use a picfmt of "....i".
The format of page numbering can also be controlled by:
.af # picfmt
There are a number of registers that are "read only" and
predefined. They are accessed as any other register would be, but
they canNOT be altered by the ".nr" command (nor by ".af"):
.F current filename
.L Line spacing value
.c number of lines read from input
.d (?) current number of lines in text or diversion output
.i current indent
.j current adjustement mode
.l current line length
.m1 current vertical margin (for command .m1)
.m2 current vertical margin (for command .m2)
.m3 current vertical margin (for command .m3)
.m4 current vertical margin (for command .m4)
.o current page offset
.p current page length
.u fill mode?
.x version number (currently 2)
.y subversion number (currently 0)
.z current diversion name
dl width of last completed diversion
dn vertical size of last completed diversion
ln current line number (.nm command)
The choice of names is strongly influenced by nroff/troff; They are
not necessarily "read only" for these other formatters.
The insert character has other properties. The
insert character can be placed into the input by repeating
it, namely, "\\" becomes "\". (useful for delaying
substitutions). For example, defining:
.ds EN (\\eqnum\\)
will identify "EN" with "(\eqnum\)" and so our equation
example above could have been:
a = b+c \EN\
Delaying the evaluation of "eqnum" until EN is invoked
(instead of when it was defined) means that the proper
numbering of equations will occur instead of wrongly
supplying the value of "eqnum" from the time that EN was
first created.
If the insert character is at the end of a line, it
negates the following newline sequence; thus the next line
is merged with the current line. For example:
antidisestab\
lishmentarianism
is equivalent to:
antidisestablishmentarianism
Yet another use of the insert character, '\', is to form a
commnet at the end of a line, in the style of nroff and troff.
Any input line that has a \" will have that and what follows in that
same line ignored by the preprocessing in the formatter.
"Macro" definitions are used when we wish to
identify several lines with an insertion. Such definitions
are created with the .de ["DEfine macro"] and completed with
the .;; ["end macro"] commands. For example, we might wish
to use the following sequence over and over again at the
start of paragraphs:
.sp 1
.ne 2
.ti +5
to separate the paragraphs by blank lines, keep them from
starting excessively close to the bottom of the page, and
indenting them 5 spaces to the right of the current left
margin. We might want to define the "command" as
"paragraph" [personally, I might call it "P", because it
would be used a lot and my typing ...]:
.de paragraph
.sp 1
.ne 2
.ti +5
.;;
Subsequently, whenever we wished to start a paragraph we
would creat a command line:
.paragraph
instead of more tediously creating every time the three
commands we mentioned above.
The names of all commands, macros, strings, and number
registers are "case sensitive". That is to say that
capitalization and/or lower case are distinguished and, say,
.Paragraph
Would not be recognized as the same sample macro we
just defined. All the "built-in" commands, those
which were listed in the command table, are also case
sensitive and are recognized on the first two letters alone,
even if arbitrary letters or numbers follow immediately.
If we had a line:
.time
it would be identified with a "time" macro definition, if
one had been created; It would not be confused with a
"Time" macro definition. If there is no "time" macro, then
it would be matched with the "built-in", .ti ["Temporary
Indent"]. The important exception is that no macro or diversion
name should be used that could result in an invocation starting
as: .{, .}, .if, .ie, or .el; these combinations are looked for
first before the macro table is checked.
There is another object formed and used somewhat
like a macro; it is called a "diversion" and is
useful for making lists such as references [or footnotes] and
tables of contents. A diversion is created or continued
with the commands: .di [DIversion] and .da [Diversion Append].
To "regurgitate" the diversion, its name is used like one uses a
macro. In contrast to nroff, troff, ROFF5, v2.0 does NOT support
nesting of diversions; be sure to end a diversion before starting or
continuing another.
Careful study of the file, "ma.", illustrates the use of
many of the macro techniques that we have found useful for document
preparation; "ma.doc" provides a user's description of the macros.
We shall present a detailed but simplified example of the
use of the above preprocessing commands to automate reference
numbering and collection.
We start by creating a register variable, "r#", to
keep track of the current reference number:
.nr r# 1
We shall use, say, "[15]" as our means to display
reference numbering. (We could have used superscripts
instead with "^+15^-"):
.ds rn [\\r#\\]
We have used "\\" so that "rn" is defined as "[\r#\] and
will be evaluated with the current reference number at the
time of use (not of the time we made this .ds definition).
By typing \rn\ we will get the reference in the form,
"[number]", that we wanted.
We want to create a diversion, "refs", into which
we will place all our references. The head of this file
will be titled with "REFERENCES":
.di refs
.ls 1
.sp 1
.ce 1
REFERENCES
.sp 2
.di
The diversion will contain (hopefully) a list of
numbered references. To make the addition of these footnotes
as painless as possible, we define two macros, "RS"
[footnote start] and "RE" [footnote end]:
.de RS
.da refs
.sp 1
\\rn\\\\
.;;
and:
.de RE
.di
.rg r# +1
.;;
The RS macro skips a line and attaches the evaluation of
\rn\ to the start of the line that follows the macro during
execution. The lines that follow the RS macro will be
diverted to "refs". The RE macro terminates the diversion
and, also, increments the reference number, r#.
We could try a very small piece of text now:
.nf
It is a nice day.\rn\
.RS
conventional expression.
.RE
It's a crummy day.\rn\
.RS
unconventional!
.RE
The formatter will generate as immediate output:
It is a nice day.[1]
It is a crummy day.[2]
and it will place into the diversion, "refs":
REFERENCES
[1]conventional expression.
[2]unconventional!
--------------------------------
A series of files can be input using the .so ["SOurce"] command.
The advantage of using .so is that inclusion can be accomplished
without a page break, nor even a line break between input files.
The .so command is like a "CALL" or "GOSUB" in that there can be
nested .so invocations; one can access a file with .so that
contains in turn a .so command, etc. It is a limitation of
ROFF5 at present to not be able to handle the .so command
from keyboard input (it could be useful). The files,
SOTEST, ONE, TWO, and THREE are provided to test and
demonstrate the .so command.
All file names referenced by .so are automatically treated
as uppercase. The naming conventions should conform to the
operating system (CP/M or MS-DOS). It is a potential limitation of
the formatter at present to not realize that "A:ZZ" would be the
same as "ZZ"; be sure to use the same form throughout!
------------------------------